/* iosLibP.h - private I/O system header file */

/* 
 * Copyright (c) 1992-2005 Wind River Systems, Inc. 
 *
 * The right to copy, distribute, modify or otherwise make use 
 * of this software may be licensed only pursuant to the terms 
 * of an applicable Wind River license agreement. 
 */ 


/*
modification history
--------------------
01r,21jul05,tcr  add System Viewer instrumentation
01q,13jul05,hya  made removability change.
01p,13apr05,hya  removed iosFdEntryXXX call from iosXXXInLine.
01o,01mar05,hya  change for user memory validation in ioctl
01n,24jan05,aeg  added prototypes for iosRtpFdReserve, etc. (SPR #106381).
01m,28apr04,dat  remove iosCloseInLine(), 96826
01l,27feb04,dat  merging iosLib with rtpIoLib
01k,17feb04,dat  separating public/private APIs
01j,05jan04,dat  92873, improved test for valid FD_ENTRY
01i,21nov03,dat  adding new refCnt macros, removing obsolete, auxValue,
		 and reserved fields from FD_ENTRY.
01h,11nov03,dat  refactored routines
01g,27oct03,dat  Adding RTP ios support, new fields
01f,20jun03,ymz  added iosObjIdFdGet and iosFdObjIdGet prototype.
01e,02apr03,ymz  objectized FDs.
01d,22dec98,lrn  add more fields to FD_ENTRY, added obsolete state
01c,09nov93,rrr  added aio support
01b,22sep92,rrr  added support for c++
01a,23aug92,jcf  written.
*/

#ifndef __INCiosLibPh
#define __INCiosLibPh

#ifdef __cplusplus
extern "C" {
#endif

#include "private/classLibP.h"
#include "private/objLibP.h"
#include "private/kernelBaseLibP.h"
#include "iosLib.h"
#include "dllLib.h"
#include "errnoLib.h"
#include "poolLib.h"
#include "taskLib.h"	/* for taskIdCurrent */

/* typedefs */

typedef struct drvEntry		/* DRV_ENTRY - entries in driver jump table */
    {
    FUNCPTR	de_create;
    FUNCPTR	de_delete;
    FUNCPTR	de_open;
    FUNCPTR	de_close;
    FUNCPTR	de_read;
    FUNCPTR	de_write;
    FUNCPTR	de_ioctl;
    FUNCPTR	de_ioctlMemValidate;
    BOOL	de_inuse;
    } DRV_ENTRY;

/* DEV_HDR structure is in ioLib.h */

typedef struct fdObjEntry /* FD_ENTRY - entries in file table */
    {
    OBJ_CORE    objCore;	/* FDs are objects */
    DEV_HDR *	pDevHdr;	/* device header for this file */
    void *	value;		/* driver open file cookie, maybe reloaded */
    void *	driverCookie;	/* driver open file cookie */
    volatile int refCnt;	/* reference count */
    DRV_ENTRY * pDrvEntry;	/* dev driver, remove support, invalidated fd drv */
    DRV_ENTRY * pDevDrvEntry;	/* device driver entry slot pointer */
    } FD_ENTRY;

/* macros */

#define fdClassId     (&fdClass)
#define fdInstClassId (&fdInstClass)

#define FD_RESERVED ((FD_ENTRY *)-1)
#define FD_ENTRY_VALID(pFd) \
	((pFd) != NULL && (pFd) != FD_RESERVED)

/*
 * FD_ENTRY_LINK cannot be used to initialize the refCnt to 1,
 * once the count reaches zero, it stays at zero.
 */

#define FD_ENTRY_LINK(pFd) \
	do { \
	    if ((pFd)->refCnt > 0) \
		(pFd)->refCnt += 1; \
	} while ((0))

#define FD_ENTRY_UNLINK(pFd) \
	do { \
	    if ((pFd)->refCnt > 0) \
		(pFd)->refCnt -= 1; \
	} while ((0))

/* variable declarations */


IMPORT OBJ_CLASS	fdClass;
IMPORT char 		ioDefPath[];
IMPORT DL_LIST 		iosDvList;
IMPORT int 		iosMaxDrivers;
IMPORT DRV_ENTRY *	drvTable;
IMPORT int 		iosMaxFiles;
IMPORT FD_ENTRY **	iosFdTable;
IMPORT POOL_ID		iosFdEntryPool;

/* functions that are available but not public */

IMPORT	int 		iosObjIdFdGet (OBJ_ID objId);
IMPORT	OBJ_ID 		iosFdObjIdGet (int fd);

/* Refactored routines to be more obj oriented these are PRIVATE */

IMPORT	int	iosKernelFdFind (void);
IMPORT	int	iosFdEntryIoctl (FD_ENTRY *, int cmd, int arg, BOOL sc);

IMPORT STATUS	iosFdEntrySet (FD_ENTRY *, DEV_HDR * pDevHdr,
				const char* name, int	value);
IMPORT	FD_ENTRY *iosFdEntryGet (void);
IMPORT	STATUS  iosFdEntryReturn (FD_ENTRY *);

IMPORT	void	iosLock (void);
IMPORT	void	iosUnlock (void);

IMPORT  int	iosRtpFdReserve (RTP_ID pRtp);
IMPORT  STATUS	iosRtpFdUnmap (RTP_ID pRtp, int fd);
IMPORT  STATUS 	iosRtpFdSetup (RTP_ID pRtp, FD_ENTRY * pFdEntry, int  fd,
			       DEV_HDR * pDevHdr, const char * name, int value);
IMPORT  STATUS 	iosRtpDefPathSet (RTP_ID pRtp, const char * pBuff);
IMPORT	int 	iosRtpFdReserve (RTP_ID pRtp);
IMPORT	STATUS	iosRtpDefPathGet (RTP_ID pRtp, char * pBuff, size_t length);
IMPORT  STATUS  iosRtpFdEntryMap (RTP_ID pRtp, int fd, FD_ENTRY * pFdEntry);
IMPORT  size_t  iosRtpFdTableSizeGet (RTP_ID pRtp);

/* Routines that used to be in iosLib.h, now 'private' */

IMPORT int 	iosOpen (DEV_HDR *pDevHdr, const char *fileName,
			int flags, int mode);
IMPORT int 	iosCreate (DEV_HDR *pDevHdr, const char *fileName, int mode);
IMPORT int 	iosDelete (DEV_HDR *pDevHdr, const char *fileName);
IMPORT int 	iosIoctl (int fd, int function, int arg);
IMPORT int 	iosRead (int fd, char *buffer, int maxbytes);
IMPORT int 	iosWrite (int fd, char *buffer, int nbytes);
IMPORT STATUS 	iosClose (int fd);

IMPORT STATUS 	iosFdSet (int fd, DEV_HDR *pDevHdr, const char *name,
			  int value);
IMPORT FD_ENTRY* iosFdMap (int fd);
extern STATUS	iosFdInvalid (DEV_HDR *pDevHdr);
extern STATUS	iosDrvIoctlMemValSet (int drvnum, FUNCPTR pIoctlMemVal);
extern STATUS	iosDrvIoctl (int drvNum, int function, int arg);

/* inline functions for speed  (in ioLib.c) */

_WRS_INLINE
STATUS iosCreateInLine
    (
    DEV_HDR * pDevHdr,
    const char * fileName,
    int flags
    )
    {
    FUNCPTR drvCreate = ((DRV_ENTRY *)pDevHdr->pDrvEntry)->de_create;

    return (*drvCreate)(pDevHdr, fileName, flags);

    }

_WRS_INLINE
STATUS iosOpenInLine
    (
    DEV_HDR *   pDevHdr,
    const char *fileName,
    int 	mode,
    int 	flags
    )
    {
    FUNCPTR drvOpen = ((DRV_ENTRY *)pDevHdr->pDrvEntry)->de_open;

    return (*drvOpen)(pDevHdr, fileName, mode, flags);

    }

_WRS_INLINE
int iosDeleteInLine
    (
    DEV_HDR *   pDevHdr,
    const char *fileName
    )
    {
    FUNCPTR drvDelete = ((DRV_ENTRY *)pDevHdr->pDrvEntry)->de_delete;

    return ((*drvDelete)(pDevHdr, fileName));

    }


_WRS_INLINE
int iosReadInLine
    (
    int fd,
    char *buffer,
    int maxbytes
    )
    {
    FD_ENTRY *pFdEntry;
#ifdef WV_INSTRUMENTATION
    int         result;
#endif /* WV_INSTRUMENTATION */
    
    if ((pFdEntry = iosFdMap(fd)) == NULL)
	return (ERROR);

#ifdef WV_INSTRUMENTATION
    result = (* pFdEntry->pDrvEntry->de_read)
                (pFdEntry->value, buffer, maxbytes);
    EVT_OBJ_STR_3 (pFdEntry, fdClassId, EVENT_IOREAD, fd, result, buffer,
                   min (result, 16), buffer);
    return result;
#else /* WV_INSTRUMENTATION */
    return ((* pFdEntry->pDrvEntry->de_read) 
		(pFdEntry->value, buffer, maxbytes));

#endif /* WV_INSTRUMENTATION */
    }

_WRS_INLINE
int iosWriteInLine
    (
    int fd,
    char *buffer,
    int nbytes
    )
    {
    FD_ENTRY *pFdEntry;

    if ((pFdEntry = iosFdMap (fd)) == NULL)
	return (ERROR);

#ifdef WV_INSTRUMENTATION
    EVT_OBJ_STR_3 (pFdEntry, fdClassId, EVENT_IOWRITE, fd, nbytes, buffer,
                   min (nbytes,16), buffer);
#endif
    return ((* pFdEntry->pDrvEntry->de_write)
                (pFdEntry->value, buffer, nbytes));
    }

_WRS_INLINE
int iosIoctlInLine
    (
    int fd,
    int cmd,
    int arg,
    BOOL syscall
    )
    {
    FD_ENTRY *pFdEntry;

    if ((pFdEntry = iosFdMap (fd)) == NULL)
	return (ERROR);

#ifdef WV_INSTRUMENTATION
    EVT_OBJ_3 (pFdEntry, fdClassId, EVENT_IOIOCTL,
               arg, cmd, fd);
#endif

    return iosFdEntryIoctl (pFdEntry, cmd, arg, syscall);
    }

_WRS_INLINE
int iosCloseInLine
    (
    int fd
    )
    {
    if (taskIdCurrent->rtpId == kernelId
     && fd >= 0 && fd <= 2)
	{
	fd = ioTaskStdGet (0, fd);
	}
    return iosRtpFdUnmap (taskIdCurrent->rtpId, fd);
    }

/* APIs that no longer exist */

IMPORT VOIDFUNCPTR	iosFdNewHookRtn _WRS_DEPRECATED("no longer exists");
IMPORT VOIDFUNCPTR	iosFdFreeHookRtn _WRS_DEPRECATED("no longer exists");

#ifdef __cplusplus
}
#endif

#endif /* __INCiosLibPh */
